﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Printing;

namespace LabelPrintSystem
{
    class ClsZebraSdk_BTActiveXCOM
    {//BT Active COM  添加COM组件
        #region event
        delegate bool DelFormatLoader(string formatName);

        public event EventHandler evt_show_log_handle;
        protected void On_evt_show_log_handle(object obj, EventArgs e)
        {
            if (this.evt_show_log_handle != null)
                this.evt_show_log_handle(obj, e);
        }
        public event EventHandler evt_complete_print_handle;
        protected void On_evt_complete_print_handle(object obj, EventArgs e)
        {
            if (this.evt_complete_print_handle != null)
                this.evt_complete_print_handle(obj, e);
        }
        public event EventHandler evt_get_engine_handle;
        protected void On_evt_get_engine_handle(object obj, EventArgs e)
        {
            if (this.evt_get_engine_handle != null)
                this.evt_get_engine_handle(obj, e);
        }
        public event EventHandler evt_complete_LoadFormat_handle;
        protected void On_evt_complete_LoadFormat_handle(object obj, EventArgs e)
        {
            if (this.evt_complete_LoadFormat_handle != null)
                this.evt_complete_LoadFormat_handle(obj, e);
        }
        #endregion

        private const string appName = "Label Print";
        private ClsPrintInfo PrintInfo;
        BarTender.Application btApp; // Declare a BarTender application variable 
        BarTender.Format btFormat;  // Declare a BarTender document variable 

        public ClsZebraSdk_BTActiveXCOM(ClsPrintInfo PInfo)
        {
            this.PrintInfo = PInfo;
        }
        public void getPrinters()
        {
            #region using System.Drawing.Printing; 获取系统打印机
            PrintDocument fPrintDocument = new PrintDocument();
            PrintInfo.DefaultPrinterName = fPrintDocument.PrinterSettings.PrinterName;//default printer
            PrintInfo.PrinterName = new List<string>();
            foreach (String fPrinterName in PrinterSettings.InstalledPrinters)
            {
                if (!PrintInfo.PrinterName.Contains(fPrinterName))
                    PrintInfo.PrinterName.Add(fPrinterName);
            }
            On_evt_get_engine_handle(this.PrintInfo, null);
            #endregion
        }
        public bool iniEngine()
        {
            // Create and start a new BarTender Print Engine.
            try
            {
                if (btApp == null)
                    btApp = new BarTender.Application(); // Create a new instance of BarTender variable 
                return true;
            }
            catch (Exception exception)
            {
                // If the engine is unable to start, a PrintEngineException will be thrown.
                On_evt_show_log_handle("bartender:无法打开进程,请确认是否已安装Bartender9.2以上企业版或企业自由版软件\r\n" + exception.Message, new ClsEventMode() { evt_mode = ClsEventMode.en_evtMode.evt_err });
                return false;
            }
        }

        public void FormatLoader()
        {
            DelFormatLoader loder = new DelFormatLoader(formatLoader_DoWork);
            loder.BeginInvoke(PrintInfo.SelectFormatName, formatLoader_RunWorkerCompleted, loder);
        }

        bool formatLoader_DoWork(string formatName)
        {
            string errorMessage = "";
            lock (btApp)
            {// We lock the engine here because the engine might still be printing a format.
                try
                {
                    if (btFormat != null)
                        btFormat.Close(BarTender.BtSaveOptions.btDoNotSaveChanges);
                    btFormat = btApp.Formats.Open(formatName);
                    //btFormat = btApp.Formats.Open(formatName, true);
                    On_evt_show_log_handle(string.Format("打开标签:{0}", formatName), null);
                    return true;
                }
                catch (System.Runtime.InteropServices.COMException comException)
                {
                    errorMessage = String.Format("无法打开标签模板:{0}\n原因: {1}", formatName, comException.Message);
                    btFormat = null;
                }
            }
            if (errorMessage.Length != 0)
            {
                On_evt_show_log_handle(errorMessage, new ClsEventMode() { evt_mode = ClsEventMode.en_evtMode.evt_err });
            }
            return false;
        }

        void formatLoader_RunWorkerCompleted(IAsyncResult result)
        {
            // We lock on the engine here so that if we have a valid format object
            // we don't lose it while we are using it.
            if ((result.AsyncState as DelFormatLoader).EndInvoke(result))
            {
                string IdenticalCopies = null;
                lock (btApp)
                {
                    if (btFormat != null)
                    {
                        // Set the number of identical copies.
                        if (btFormat.SupportsSetIdenticalCopies == false)
                        {
                            //PrintInfo.IdenticalCopies = null;
                        }
                        else
                        {
                            IdenticalCopies = btFormat.IdenticalCopiesOfLabel.ToString();
                        }

                        // Set the number of serialized copies.
                        if (btFormat.SupportsSetSerializedCopies == false)
                        {
                            PrintInfo.SerializedCopies = null;
                        }
                        else
                        {
                            PrintInfo.SerializedCopies = btFormat.NumberSerializedLabels.ToString();
                        }


                        // Set the substrings grid.
                        if (btFormat.NamedSubStrings.Count > 0)
                        {
                            PrintInfo.FormatSubStrings = new Dictionary<string, string>();
                            foreach (BarTender.SubString sub in btFormat.NamedSubStrings)
                            {
                                PrintInfo.FormatSubStrings.Add(sub.Name, sub.Value);
                            }
                        }
                        else
                        {
                            PrintInfo.FormatSubStrings = null;
                        }
                    }
                }
                string str = string.Format("重复数量:{0}\r\n序列化数量:{1}\r\n", IdenticalCopies == null ? "不启用" : IdenticalCopies, PrintInfo.SerializedCopies == null ? "不启用" : PrintInfo.SerializedCopies);
                if (PrintInfo.FormatSubStrings != null)
                {
                    str += "数据关联(共享/名称):\r\n";
                    foreach (string key in PrintInfo.FormatSubStrings.Keys)
                    {
                        str += string.Format("-->{0}:{1}\r\n", key, PrintInfo.FormatSubStrings[key]);
                    }
                    str = str.Substring(0, str.Length - 2);
                }
                else
                {
                    str += string.Format("数据关联(共享/名称):\r\n-->null");
                }
                On_evt_show_log_handle(str, null);
                On_evt_complete_LoadFormat_handle(PrintInfo, null);
            }
            else
            {
                On_evt_show_log_handle("无法打开标签模板", new ClsEventMode() { evt_mode = ClsEventMode.en_evtMode.evt_err });
            }
        }

        public void PrintLabel(int IdenticalCopies = 1, int SerializedCopies = 1)
        {
            // We lock on the engine here so we don't lose our format object
            // if the user were to click on a format that wouldn't load.
            lock (btApp)
            {
                if (btFormat != null)
                {
                    On_evt_show_log_handle("打印设置", null);
                    bool success = true;
                    // Assign number of identical copies if it is not datasourced.
                    if (btFormat.SupportsSetIdenticalCopies)
                    {
                        btFormat.IdenticalCopiesOfLabel = Convert.ToInt32(PrintInfo.IdenticalCopies);
                        On_evt_show_log_handle("重复数量: " + btFormat.IdenticalCopiesOfLabel, null);
                    }
                    else
                    {
                        On_evt_show_log_handle("重复数量: null", null);
                    }
                    // Assign number of serialized copies if it is not datasourced.
                    if (btFormat.SupportsSetSerializedCopies)
                    {
                        btFormat.NumberSerializedLabels = SerializedCopies;
                        On_evt_show_log_handle("序列化数量: " + btFormat.NumberSerializedLabels, null);
                    }
                    else
                    {
                        On_evt_show_log_handle("序列化数量: null", null);
                    }

                    // Set the substrings grid.
                    if (btFormat.NamedSubStrings.Count > 0)
                    {
                        /* 2017/11/27  二维码里面的信息不允许加入前缀和后缀，否则substring获取的是加了前缀和后缀的信息，设定setsubstring后模板会自动再次加入后缀，导致信息重复，处理方法：模板将前缀后缀直接放到嵌入数据框内，或者改用VB脚本的方式生成二维码信息
                         * */
                        if (PrintInfo.FormatSubStringsChange != null)
                        {
                            string str = "数据关联(共享/名称)更改:\r\n";
                            foreach (string key in PrintInfo.FormatSubStringsChange.Keys)
                            {
                                btFormat.SetNamedSubStringValue(key, PrintInfo.FormatSubStringsChange[key]);
                                str += string.Format("-->{0}:{1}\r\n", key, btFormat.GetNamedSubStringValue(key));
                            }
                            str = str.Substring(0, str.Length - 2);
                            On_evt_show_log_handle(str, null);
                        }
                    }
                    else
                    {
                        On_evt_show_log_handle("数据关联(共享/名称)更改:-->null", null);
                    }

                    // If there are no incorrect values in the copies boxes then print.
                    if (success)
                    {
                        // Get the printer from the dropdown and assign it to the format.
                        if (PrintInfo.SelectPrinterName != null && PrintInfo.SelectPrinterName != "")
                            btFormat.Printer = PrintInfo.SelectPrinterName;
                        On_evt_show_log_handle(string.Format("打印机名:{0}", btFormat.Printer), null);


                        BarTender.Messages messages;
                        int waitForCompletionTimeout = 5000; // 5 seconds
                        //btFormat.PrintOut();
                        BarTender.BtPrintResult result = btFormat.Print(appName, false, waitForCompletionTimeout, out messages);

                        string messageString = "\n\nMessages:";
                        messageString += "\n\n" + messages.ToString();

                        if (result == BarTender.BtPrintResult.btFailure)
                        {
                            On_evt_show_log_handle("打印失败", new ClsEventMode() { evt_mode = ClsEventMode.en_evtMode.evt_err });
                        }
                        else if (result == BarTender.BtPrintResult.btTimeout)
                        {
                            On_evt_show_log_handle("打印超时", new ClsEventMode() { evt_mode = ClsEventMode.en_evtMode.evt_err });
                        }
                        else
                        {
                            On_evt_show_log_handle("打印成功", null);
                        }
                    }
                }
                On_evt_complete_print_handle(null, null);
            }
        }

        public void StartPrint()
        {

        }

        public void StopPrint()
        {
            // Quit the BarTender Print Engine, but do not save changes to any open formats.
            if (btApp != null)
                btApp.Quit(BarTender.BtSaveOptions.btDoNotSaveChanges);
        }

        public void EngineVisible(bool isVisible, string labelName)
        {//将模板显示给用户，用次方法有BUG，再次使用会导致软件闪退，改用进程打开模板的方式--> OpenFormatProcsss
            //lock (engine)
            //{
            //    //if (engine == null) return;
            //    engine.Window.Visible = false;
            //    // engine.Documents.CloseAll(SaveOptions.DoNotSaveChanges);
            //    if (labelName != null)
            //    {
            //        engine.Documents.Open(labelName);
            //        engine.Window.Visible = isVisible;
            //    }
            //}
        }

        public void OpenFormatProcsss(string labelFormatName)
        {
            try
            {
                System.Diagnostics.Process.Start(labelFormatName);
                On_evt_show_log_handle("模板已在Bartender软件打开,请查看下方任务栏BT软件", new ClsEventMode(ClsEventMode.en_evtMode.evt_Tips));
            }

            catch (Exception ex)
            {
                On_evt_show_log_handle(string.Format("无法打开标签模板:{0}", ex.ToString()), new ClsEventMode() { evt_mode = ClsEventMode.en_evtMode.evt_err });
            }
        }
    }
}
